package org.jeecg.modules.monitoring.j_monitoring.facilities;

import com.alibaba.fastjson.JSON;
import com.xkcoding.http.util.StringUtil;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.sign.util.NoSslHttpUtils;
import org.jeecg.config.vo.HttpResult;
import org.jeecg.modules.monitoring.j_monitoring.constantConfig.RoomRedisEnum;
import org.jeecg.modules.monitoring.j_monitoring.entity.*;
import org.jeecg.modules.monitoring.j_monitoring.entity.donghuan.*;
import org.jeecg.modules.monitoring.j_monitoring.mapper.*;
import org.jeecg.modules.monitoring.j_monitoring.service.impl.RingDevicesServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import jakarta.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 动环token
 */

@Component
public class FacilitiesToken {


    @Autowired
    private Environment env;

    private String[] roomList = {"数据机房","网络机房","UPS间"};

    @Resource
    private RingMonitorMapper ringMonitorMapper;
    @Resource
    private RingDevicesMapper ringDevicesMapper;
    @Resource
    private RingDevicesServiceImpl ringDevicesService;
    @Resource
    private RingWarningMapper warningMapper;
    @Resource
    private RingTemLogMapper temLogMapper;
    @Resource
    private RingSpaceMapper spaceMapper;
    @Resource
    private RingDevicesMapper devicesMapper;
    @Resource
    private RingMonitorMapper monitorMapper;
    @Resource
    private RedisUtil redisUtil;
    /**
     * 获取token
     */
    public String getToken(){

        GetTokenRequestDo requestDo = new GetTokenRequestDo();
        GetTokenRequestDataDo dataDo = new GetTokenRequestDataDo();
        requestDo.setVersion(env.getProperty("donghuan.version"));
        dataDo.setIp(env.getProperty("donghuan.selfIp"));
        dataDo.setPort(env.getProperty("donghuan.selfPort"));
        dataDo.setUsername(env.getProperty("donghuan.userName"));
        dataDo.setPassword(env.getProperty("donghuan.passWord"));
        requestDo.setData(dataDo);
        String url = env.getProperty("donghuan.url") + "/north/login";

        HttpResult res = NoSslHttpUtils.noSslPost(url, "",requestDo);
        String json = res.getBody();
        TokenResultDo resultDo = JSON.parseObject(json, TokenResultDo.class);
        if (resultDo.getErrorCode() == 0 ){
            return resultDo.getData().getToken();
        }
        return "";
    }


    /**
     * 延续token时常
     */
    public void heartToken(){
//        if (StringUtil.isEmpty(this.token)){
//            getToken();
//        }
//        String url = env.getProperty("donghuan.url") + "/north/heart";
//
//        GetTokenRequestDo requestDo = new GetTokenRequestDo();
//        requestDo.setVersion(env.getProperty("donghuan.version"));
//
//        HttpResult res = NoSslHttpUtils.noSslPost(url, this.token,requestDo);
//
//        HeartTokenResultDo resultDo = JSON.parseObject(res.getBody(), HeartTokenResultDo.class);
//        System.out.println("heartToken"+res.getBody());
//        if (resultDo.getErrorCode() != 0 ){
//            System.out.println(resultDo.getErrorCode());
//            this.token = null;
//            getToken();
//        }

    }


    /**
     * 同步设备
     */
    public void syncDevice() {
        try {

            GetTokenRequestDo requestDo = new GetTokenRequestDo();
            requestDo.setVersion(env.getProperty("donghuan.version"));
            String url = env.getProperty("donghuan.url") + "/north/get_device_list";
            HttpResult res = NoSslHttpUtils.noSslPost(url, getToken() ,requestDo);
            String json = res.getBody();

            devicesRequest request = JSON.parseObject(json, devicesRequest.class);

            if (request.getData().getResources().size()>0){
                ringDevicesMapper.deleteAll();
            }

            for (RingDevices devices : request.getData().getResources()){
                ringDevicesMapper.insertSelective(devices);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 同步设备
     */
    public void syncSpace() {
        try {

            GetTokenRequestDo requestDo = new GetTokenRequestDo();
            requestDo.setVersion(env.getProperty("donghuan.version"));
            String url = env.getProperty("donghuan.url") + "/north/get_space_list";
            HttpResult res = NoSslHttpUtils.noSslPost(url, getToken() ,requestDo);
            String json = res.getBody();

            devicesRequest request = JSON.parseObject(json, devicesRequest.class);

            for (RingDevices devices : request.getData().getResources()){
                ringDevicesMapper.insertSpace(devices);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 同步设备
     */
    public void syncMonitor() {
        try {

            List<RingDevices> ringDevicesList = ringDevicesService.getAllList();

            SpotRequestDo spotRequestDo = new SpotRequestDo();
            SpotRequestDataDo dataDo = new SpotRequestDataDo();
            spotRequestDo.setVersion(env.getProperty("donghuan.version"));
            List<String> stringList = new ArrayList<>();
            for (RingDevices devices : ringDevicesList){
                stringList.add(devices.getResourceId());
            }
            dataDo.setResource_ids(stringList);
            spotRequestDo.setData(dataDo);

            String url = env.getProperty("donghuan.url") + "/north/get_spot_list";
            HttpResult res = NoSslHttpUtils.noSslPost(url, getToken(),spotRequestDo);
            String json = res.getBody();
            monitorRequest request = JSON.parseObject(json, monitorRequest.class);

            for (monitorDevices monitorDevices : request.getData().getDevices()){

                for (RingMonitor monitor : monitorDevices.getPoints()){
                    ringMonitorMapper.insertSelective(monitor);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 获取实时数据
     * @return
     */
    public String getOnlineData(List<String> stringList){

        try {

            if(!"prod".equals(env.getProperty("spring.profiles.active"))){

                File jsonFile = ResourceUtils.getFile("classpath:jsonFile/donghuan/itSpace.json");

                return CommonUtils.getStr(jsonFile);
            }


            OnlineRequestDo onlineRequestDo = new OnlineRequestDo();
            OnlineRequestDataDo dataDo = new OnlineRequestDataDo();
            onlineRequestDo.setVersion(env.getProperty("donghuan.version"));
            dataDo.setDevice_ids(stringList);
            onlineRequestDo.setData(dataDo);

            String url = env.getProperty("donghuan.url") + "/north/online_data";
            HttpResult res = NoSslHttpUtils.noSslPost(url, this.getToken() ,onlineRequestDo);

            return res.getBody();

        }catch (Exception e){
            e.printStackTrace();
            return "";
        }

    }

    public void syncWarning(){
        try {

            List<RingDevices> devicesList = ringDevicesMapper.selectAllList();
            List<String> devicesIdList = devicesList.stream().map(e -> e.getResourceId()).collect(Collectors.toList());
            String res = this.getHistoryWarning(devicesIdList);
            HistoryWarningResultDo warningResultDo = JSON.parseObject(res, HistoryWarningResultDo.class);

            if (warningResultDo.getErrorCode()!=0){
                return;
            }

            if (warningResultDo.getData().getAlarm().size()==0){
                return;
            }

            warningMapper.removeAll();

            List<RingWarning> newWariningList = warningResultDo.getData().getAlarm();
            this.saveWarningToRedis(newWariningList);

            for (RingWarning warning : newWariningList){
                warningMapper.insertSelective(warning);
            }


        }catch (Exception e){
            e.printStackTrace();
        }


    }

    public String getHistoryWarning(List<String> stringList){
        try {

            if(!"prod".equals(env.getProperty("spring.profiles.active"))){

                File jsonFile = ResourceUtils.getFile("classpath:jsonFile/donghuan/warning.json");
                return CommonUtils.getStr(jsonFile);
            }


            OfflineRequestDo requestDo = new OfflineRequestDo();
            OfflineWarningDataDo dataDo = new OfflineWarningDataDo();
            requestDo.setVersion(env.getProperty("donghuan.version"));
            dataDo.setResource_id(stringList);
            dataDo.setBegin_time((int) DateUtils.getMonthDate(-1)/1000);


            long endTime = System.currentTimeMillis() / 1000;
            dataDo.setEnd_time((int) endTime);
            requestDo.setData(dataDo);

            String url = env.getProperty("donghuan.url") + "/north/offline_alarm";
            HttpResult res = NoSslHttpUtils.noSslPost(url, getToken() ,requestDo);
            return res.getBody();

        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }


    public void saveTemLog(){

        temLogMapper.deleteLog();
        for (String name : this.roomList){

            RingTemLog log = new RingTemLog();
            log.setId(UUID.randomUUID().toString().replace("-", ""));
            log.setName(name);
            log.setCreateTime(new Date());


            RingSpace space = spaceMapper.selectByName(name);
            if (space==null){
                return;
            }

            List<RingDevices> devicesList = devicesMapper.selectByParentId(space.getResourceId());
            List<String> deviceIdList = devicesList.stream().map(e -> e.getResourceId()).collect(Collectors.toList());

            //ups监控点列表
            List<RingMonitor> monitorList = monitorMapper.selectByParentIds(deviceIdList);

            String json = this.getOnlineData(deviceIdList);
            realDataRequest request = JSON.parseObject(json, realDataRequest.class);
            List<realPoints> pointsList = request.getData().getPoints();
            if (pointsList.size()==0){
                return;
            }

            BigDecimal tem = new BigDecimal(0);//温度
            BigDecimal hum = new BigDecimal(0);//湿度
            int temCount = 0;
            int humCount = 0;

            for (RingMonitor monitor : monitorList){

                if ("温度".equals(monitor.getName())){
                    String value = this.getDataValue(monitor.getResourceId(),pointsList);

                    if (!StringUtil.isEmpty(value)){
                        tem = tem.add(new BigDecimal(value));
                        temCount++;
                    }
                }

                if ("湿度".equals(monitor.getName())){

                    String value = this.getDataValue(monitor.getResourceId(),pointsList);
                    if (!StringUtil.isEmpty(value)){
                        humCount++;
                        hum = hum.add(new BigDecimal(value));
                    }
                }

            }
            if(temCount>0){
                BigDecimal temResult = tem.divide(new BigDecimal(temCount),BigDecimal.ROUND_CEILING).setScale(2, RoundingMode.HALF_UP);
                log.setTem(temResult);
            }
            if (humCount>0){
                BigDecimal humResult = hum.divide(new BigDecimal(humCount),BigDecimal.ROUND_CEILING).setScale(2, RoundingMode.HALF_UP);
                log.setHum(humResult);
            }


            temLogMapper.insert(log);
        }



    }

    public String getDataValue(String id, List<realPoints> pointsList){
        for (realPoints points : pointsList){
            if (id.equals(points.getResourceId())){
                return points.getRealValue();
            }
        }
        return "";
    }

    public void saveWarningToRedis(List<RingWarning> list){

        List<RingWarning> netRoom = new ArrayList<>();//网络机房
        List<RingWarning> dataRoom = new ArrayList<>();//数据机房
        List<RingWarning> upsRoom = new ArrayList<>();//ups机房
        for (RingWarning warning : list){

            if (warning.getEventSource().contains(RoomRedisEnum.netRoom.getValue())){
                netRoom.add(warning);
            }

            if (warning.getEventSource().contains(RoomRedisEnum.dataRoom.getValue())){
                dataRoom.add(warning);
            }

            if (warning.getEventSource().contains(RoomRedisEnum.upsRoom.getValue())){
                upsRoom.add(warning);
            }
        }

        redisUtil.set(RoomRedisEnum.netRoom.getKey(),netRoom);
        redisUtil.set(RoomRedisEnum.dataRoom.getKey(),dataRoom);
        redisUtil.set(RoomRedisEnum.upsRoom.getKey(),upsRoom);

    }


}
